﻿// Copyright 2007-2009 NSynthesis Project(Stuart Caborn, Alex Scordellis)
//  
//  http://www.apache.org/licenses/LICENSE-2.0
// 

using System;
using NAnt.Core;
using NAnt.Core.Attributes;

namespace NSynthesis.Tasks
{
    [TaskName("NSynthesis")]
    public class NSynthesisReportTask : Task
    {
        [TaskAttribute("reportFile", Required = true)]
        [StringValidator(AllowEmpty = false)]
        public string ReportFile { get; set; }

        protected override void ExecuteTask()
        {
            Log(Level.Info, "Processing log file {0}", ReportFile);
            
            var report = LoadReport();

            Log(Level.Info, string.Format("{0} Mocked Calls To Process", report.MockedMethods.Count));
            
            if (report.HasErrors)
            {
                LogErrors(report);

                throw new BuildException(ErrorMessageFor(report));
            }

            Log(Level.Info, "All mocked calls resolved");
        }

        
        private Report LoadReport()
        {
            Report report;
            try
            {
                report = Report.Load(ReportFile);
            }
            catch (Exception e)
            {
                Log(Level.Error, "Failed to load synthesis log file");
                throw new BuildException("Could not process log file", e);
            }
            return report;
        }

        private static string ErrorMessageFor(Report report)
        {
            return string.Format("Synthesis detected {0} error{1}!", report.Errors.Count, report.Errors.Count == 1 ? "" : "s");
        }

        private void LogErrors(Report report)
        {
            foreach (var errorDescription in report.Errors)
                LogError(errorDescription);
        }

        private void LogError(Report.ErrorDescription errorDescription)
        {
            if (errorDescription.MissingMethod != null)
            {
                Log(Level.Error, string.Format("UNTESTED: {0}", errorDescription.MissingMethod));
            }
            else
            {
                Log(Level.Error, string.Format("MISSING IMPLEMENTATION for: {0}", errorDescription.MockedMethod));
            }
        }

    }
}